package com.kk.solr.rest;


import com.kk.solr.service.SolrService;
import com.kk.solr.service.dto.SolrFileDTOWrapper;
import com.kk.solr.service.dto.SolrFileQueryCriteria;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.aop.log.Log;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.common.SolrDocumentList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;

@RestController
@RequestMapping("solr")
@Slf4j
public class SolrController {

    @Value("${spring.data.solr.host}")
    private String mSolrHost;
    @Value("${spring.data.solr.core}")
    private String mSolrCore;

    private final SolrService mSolrService;

    @Autowired
    public SolrController(SolrService mSolrService) {
        this.mSolrService = mSolrService;
    }

    @Log(value = "文档简单搜索")
    @RequestMapping("/search/{q}")
    public ResponseEntity<SolrFileDTOWrapper> search(@PathVariable String q) {
        SolrFileQueryCriteria criteria = new SolrFileQueryCriteria();
        criteria.setValue(q);
        criteria.setType("keyword");
        Pageable pageable = PageRequest.of(0, 20);
        return searchAdvance(criteria, pageable);
    }

    @Log(value = "文档搜索")
    @RequestMapping("/search-advance")
    @PreAuthorize("hasAnyRole('ADMIN','USER_ALL','USER_SELECT')")
    public ResponseEntity<SolrFileDTOWrapper> searchAdvance(SolrFileQueryCriteria criteria, Pageable pageable) {
        try {
            log.info("solr search:{}, {}", criteria, pageable);
            SolrDocumentList solrDocumentList = mSolrService.querySolrAdvance(mSolrCore, criteria, pageable);
            SolrFileDTOWrapper wrapper = new SolrFileDTOWrapper();
            wrapper.setContent(solrDocumentList);
            wrapper.setTotalElements(solrDocumentList.getNumFound());
            return new ResponseEntity<>(wrapper, HttpStatus.OK);
        } catch (IOException | SolrServerException e) {
            e.printStackTrace();
            log.error("Error in search:{}, {}", criteria, pageable);
        }
        return new ResponseEntity<>(null, HttpStatus.EXPECTATION_FAILED);
    }

    @Log(value = "增量Index")
    @PostMapping(value = "/deltaIndex")
    @PreAuthorize("hasAnyRole('ADMIN')")
    public ResponseEntity<String> deltaIndex() {
        return doIndex(false);
    }

    @Log(value = "重新Index")
    @PostMapping(value = "/reIndex")
    @PreAuthorize("hasAnyRole('ADMIN')")
    public ResponseEntity<String> reIndex() {
        return doIndex(true);
    }

    private ResponseEntity<String> doIndex(boolean fullIndex) {
        String errorMsg;
        try {
            boolean result;
            if (fullIndex) {
                result = mSolrService.reIndex(mSolrCore);
            } else {
                result = mSolrService.deltaIndex(mSolrCore);
            }
            if (result) {
                return new ResponseEntity<>("success", HttpStatus.OK);
            }
            errorMsg = "ReIndex Failed";
        } catch (IOException | SolrServerException e) {
            e.printStackTrace();
            errorMsg = e.getMessage();
        }
        return new ResponseEntity<>(errorMsg, HttpStatus.EXPECTATION_FAILED);
    }

    @Log(value = "上传文件")
    @PostMapping(value = "/solrFile")
    @PreAuthorize("hasAnyRole('ADMIN','USER_ALL','USER_SELECT')")
    public ResponseEntity uploadFile(@RequestParam("files") MultipartFile[] files) {
        boolean success = mSolrService.upload(files);
        log.info("Do delta index after file upload");
        doIndex(false);
        return new ResponseEntity(success ? HttpStatus.OK : HttpStatus.EXPECTATION_FAILED);
    }
}
